package com.htjc.integral.account.service.impl;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.htjc.integral.account.mapper.newdb.EcBpAccountIntegralDetailMapper;
import com.htjc.integral.account.mapper.newdb.EcBpAcctResultDetailMapper;
import com.htjc.integral.account.mapper.newdb.EcBpAcctResultMapper;
import com.htjc.integral.account.service.IAccountCheckService;
import com.htjc.integral.account.util.enums.NewAccountConstant;
import com.htjc.integral.common.util.TimeUtil;
import com.htjc.integral.common.util.UUIDUtil;
import com.htjc.integral.model.newaccount.EcBpAccountIntegralDetail;
import com.htjc.integral.model.newaccount.checkacct.AcctResult;
import com.htjc.integral.model.newaccount.checkacct.AcctResultDetail;
import com.htjc.integral.model.newaccount.checkacct.DetailRow;

import lombok.extern.slf4j.Slf4j;

/**
 * 对账业务实现类
 * @author hlc
 *
 */
@Slf4j(topic = "jfLog")
@Service
public class AccountCheckServiceImpl implements IAccountCheckService{
	
	/** 积分账户明细表  */
	@Autowired
	private EcBpAccountIntegralDetailMapper accountIntegralDetailMapper;
	
	@Autowired
	private EcBpAcctResultMapper acctResultMapper;
	
	@Autowired
	private EcBpAcctResultDetailMapper acctResultDetailMapper;
	
	@Value("${CHECK_FILE_URL}")
	private String fileUrl;
	
	/**
	 * 对账--00：缴费积分抵扣（浙江调用）   02：网省活动积分派发（欣航调用） 
	 * @param jsonObject
	 * @return
	 */
	public String check(JSONObject jsonObject) {
		String resultStr=null;
		String acctDate=jsonObject.getString("acctDate");//对账日期
		String bussType=jsonObject.getString("bussType");//业务类型
		String logMsg="【"+bussType+"积分对账】";
		
		//文件名：JF_PF_YYYYMMdd.txt
		String url=fileUrl+NewAccountConstant.CHECK_MAP.get(bussType)+"/"+
				NewAccountConstant.CHECK_MAP.get(bussType)+"_33101_"+acctDate+".txt";
//		if(NewAccountConstant.BUSS_TYPE_WSHDJFPF.equals(bussType)){
			Map<String, Object> params=new HashMap<String, Object>(); 
			params.put("acctDate", acctDate);
			params.put("bussType", bussType);
			//总积分和明细条数
			Map<String, Object> map = accountIntegralDetailMapper.selectTotal(params);
			//明细
			List<EcBpAccountIntegralDetail> detailList = accountIntegralDetailMapper.selectByDateAndBussType(params);
			FileWriter fw=null;
			try {
				fw=new FileWriter(url);
				//汇总行：日期|总积分|总笔数
				fw.write(acctDate+"|"+map.get("BALANCE")+"|"+map.get("NUM"));
				fw.write("\r\n");
				for (EcBpAccountIntegralDetail detail : detailList) {
					//明细行：流水号|积分|交易时间
					fw.write(detail.getSerialNo()+"|"+detail.getBalance()+"|"+detail.getCreateTime());
					fw.write("\r\n");
				}
			} catch (IOException e) {
				log.error(logMsg+"路径不存在");
			} finally{
				try {
					if(fw!=null)
						fw.close();
						log.info(logMsg+"对账文件生成成功,路径:"+url);
				} catch (IOException e) {
					log.error(logMsg+"流关闭失败");
				}
			}
//		}
		//如果是00：缴费积分抵扣，直接读取文件
		InputStream inputStream=null;
		try {
			File file=new File(url);
			inputStream=new FileInputStream(file);
			BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));    
	        StringBuilder sb = new StringBuilder();    
	        String line = null; 
	        while ((line = reader.readLine()) != null) {    
                sb.append(line + "\r\n");    
            }   
	        resultStr=sb.toString();
		} catch (FileNotFoundException e) {
			log.error(logMsg+"路径不存在");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		return resultStr;
	}
	
	
	/**
     * 
	 * @throws Exception 
     */
    @SuppressWarnings("resource")
	@Scheduled(cron= "0 0 3 * * ?")
    public void deductionCheck() throws Exception{
    	String acctDate=TimeUtil.getDate("YYYYMMdd");//账务日期
    	String bussTypes[]={NewAccountConstant.BUSS_TYPE_JFJFDK,NewAccountConstant.BUSS_TYPE_WSHDJFPF};
    	for (String bussType : bussTypes) {
    		String logMsg="【积分对账跑批"+bussType+"】";
			//调用姚远接口，获取对账文件流
			log.info(logMsg+"接口调用成功，获取对账文件，开始解析文件");
			//对账文件读取为List
			Map<String, DetailRow> fileMap=new HashMap<String, DetailRow>();
			FileReader fr = new FileReader("E:\\test\\JF_PF\\JF_PF20181107.txt");
			BufferedReader br = new BufferedReader(fr);
			
			//对账文件汇总行
//			TotalRow totalRow=new TotalRow();
//			int i=0;
			String str = null;
			while((str = br.readLine()) != null) {
				String[] strs = str.split("\\|");
//				if(i==0){
//					totalRow.setProCode(strs[0]);//省码
//					totalRow.setAcctDate(strs[1]);//账务日期
//					totalRow.setTotalIntegral(strs[2]);//总积分值
//					totalRow.setTotalNum(strs[3]);//总笔数
//				}else{
					DetailRow detailRow=new DetailRow();
					detailRow.setBussTypeDiscrible(strs[0]);//业务类型+业务描述
					detailRow.setSerialNo(strs[1]);//流水号
					detailRow.setIntegral(new BigDecimal(strs[2]));//积分值
					detailRow.setDealType(strs[3]);//收支芳芳
					detailRow.setAccountId(strs[4]);//账户ID
					fileMap.put(strs[1], detailRow);//key=流水号；value=DetailRow
//				}
//		        i=1;
			}
			//判断对账文件中的账务日期是否正确
//			if(!acctDate.equals(totalRow.getAcctDate())){
//				log.error(logMsg+"对账文件中的账务日期（{}）不正确",totalRow.getAcctDate());
//				//落库
//				return;
//			}
			//查询自己数据库中的数据
			Map<String, Object> params=new HashMap<String, Object>(); 
			params.put("acctDate", acctDate);
			params.put("bussType", bussType);
			//总积分和明细条数
//			Map<String, Object> map = accountIntegralDetailMapper.selectTotal(params);
			//判断对账文件中的 总积分值 跟 数据库中的总积分值 是否一致
//			if(!totalRow.getTotalIntegral().equals(map.get("BALANCE"))){
//				log.error(logMsg+"对账文件中的总积分值（{}）跟数据库中的总积分值（{}）不一致",totalRow.getTotalIntegral(),map.get("BALANCE"));
//			}
			//明细
			List<EcBpAccountIntegralDetail> detailList = accountIntegralDetailMapper.selectByDateAndBussType(params);
			//将list转为map
			Map<String, DetailRow> databaseMap=new HashMap<String, DetailRow>();
			for (EcBpAccountIntegralDetail detail : detailList) {
				DetailRow detailRow=new DetailRow();
				detailRow.setBussTypeDiscrible(detail.getBussType()+detail.getBussDiscrible());//业务类型+业务描述
				detailRow.setSerialNo(detail.getSerialNo());//流水号
				detailRow.setIntegral(detail.getBalance());//积分值
				detailRow.setDealType(detail.getDealType());//收支方向
				detailRow.setAccountId(detail.getAccountId());//账户ID
				databaseMap.put(detail.getSerialNo(), detailRow);//key=流水号；value=DetailRow
			}
			
			//积分对账总表主键ID
			String resultId=UUIDUtil.getUUID();
			//对账结果list
			List<AcctResultDetail> acctResultDetailList=new ArrayList<AcctResultDetail>();
			
			int num_01=0;//失败类型：01：我有对方没有的数量
			int num_02=0;//失败类型：02：对方有我没有的数量
			int num_03=0;//失败类型：03：积分值不一致的数量
			//对比 databaseMap和fileMap
			for(String dKey:databaseMap.keySet()){
				AcctResultDetail acctResultDetail=new AcctResultDetail();
				acctResultDetail.setDetailId(UUIDUtil.getUUID());//明细ID
				acctResultDetail.setResultId(resultId);//总表主键ID
				acctResultDetail.setSerialNo(dKey);//流水号
				acctResultDetail.setAcctDate(acctDate);//账务日期
				acctResultDetail.setDealType(databaseMap.get(dKey).getDealType());//收支方向
				acctResultDetail.setWfIntegral(databaseMap.get(dKey).getIntegral());//我方积分值
				acctResultDetail.setStatus(NewAccountConstant.ACCT_DETAIL_STAUS_WCL);//状态01：未处理
				if(fileMap.get(dKey)==null){
					log.error(logMsg+"对账文件中少流水号（{}），积分值（{}）",dKey,databaseMap.get(dKey).getIntegral());
					acctResultDetail.setFailType(NewAccountConstant.ACCT_FAIL_TYPE_WYDFMY);//失败类型01：我有对方没有
					acctResultDetailList.add(acctResultDetail);
					num_01++;
				}else if(!databaseMap.get(dKey).getIntegral().equals(fileMap.get(dKey).getIntegral())){
					log.error(logMsg+"流水号（{}）的积分值（{}）跟数据库中的积分值（{}）不一致",dKey,fileMap.get(dKey).getIntegral(),databaseMap.get(dKey).getIntegral());
					acctResultDetail.setDfIntegral(fileMap.get(dKey).getIntegral());//对方积分值
					acctResultDetail.setFailType(NewAccountConstant.ACCT_FAIL_TYPE_JFZBYZ);//失败类型03：积分值不一致
					acctResultDetailList.add(acctResultDetail);
					num_03++;
				}
			}
			
			//对比 fileMap和databaseMap
			for(String fKey:fileMap.keySet()){
				AcctResultDetail acctResultDetail=new AcctResultDetail();
				acctResultDetail.setDetailId(UUIDUtil.getUUID());//明细ID
				acctResultDetail.setResultId(resultId);//总表主键ID
				acctResultDetail.setSerialNo(fKey);//流水号
				acctResultDetail.setAcctDate(acctDate);//账务日期
				acctResultDetail.setDealType(fileMap.get(fKey).getDealType());//收支方向
				acctResultDetail.setDfIntegral(fileMap.get(fKey).getIntegral());//对方积分值
				acctResultDetail.setStatus(NewAccountConstant.ACCT_DETAIL_STAUS_WCL);//状态01：未处理
				if(databaseMap.get(fKey)==null){
					log.error(logMsg+"对账文件中多流水号（{}），积分值（{}）",fKey,fileMap.get(fKey).getIntegral());
					acctResultDetail.setFailType(NewAccountConstant.ACCT_FAIL_TYPE_DFYWMY);//失败类型02：对方有我没有
					acctResultDetailList.add(acctResultDetail);
					num_02++;
				}else if(!databaseMap.get(fKey).getIntegral().equals(fileMap.get(fKey).getIntegral())){
					log.error(logMsg+"流水号（{}）的积分值（{}）跟数据库中的积分值（{}）不一致",fKey,fileMap.get(fKey).getIntegral(),databaseMap.get(fKey).getIntegral());
					acctResultDetail.setWfIntegral(databaseMap.get(fKey).getIntegral());//我方积分值
					acctResultDetail.setFailType(NewAccountConstant.ACCT_FAIL_TYPE_JFZBYZ);//失败类型03：积分值不一致
					acctResultDetailList.add(acctResultDetail);
					num_03++;
				}
			}
			int failNum=acctResultDetailList.size();//对账失败条数
			//积分对账总表
			AcctResult acctResult=new AcctResult();
			acctResult.setResultId(resultId);//主键ID
			acctResult.setAcctDate(acctDate);//账务日期YYYYMMdd
			acctResult.setBussType(bussType);//业务类型
			acctResult.setFailNum(new BigDecimal(failNum));//失败条数
			acctResult.setStatus(failNum==0?NewAccountConstant.ACCT_RESULT_SUCCESS:NewAccountConstant.ACCT_RESULT_FAIL);
			acctResultMapper.insert(acctResult);
			log.info(logMsg+"积分对账总表插入成功，失败条数："+failNum);
			if(acctResultDetailList.size()!=0){
				//对账失败结果集插入 积分对账结果明细表
				acctResultDetailMapper.insertList(acctResultDetailList);
				log.info(logMsg+"积分对账明细表插入成功，01条数："+num_01+",02条数："+num_02+",03条数："+num_03);
				//处理失败结果
				for (AcctResultDetail acctResultDetail : acctResultDetailList) {
					//01：我有对方没有，则直接同步至资产中心
					if(acctResultDetail.getFailType().equals(NewAccountConstant.ACCT_FAIL_TYPE_WYDFMY)){
						
					}
				}
				
				
				
			}
			
			
    	}
    }
    
}
